<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  
  <script>
    /**
     * 面向对象有三大特性: 封装\继承\多态
     * 继承: 1.减少重复的代码 2.多态的前提(鸭子类型)
     */

    class Person {
      // 类的属性和方法，除非显式定义在其本身（即定义在this对象上）
      constructor(name, age) {
        this.name = name;
        this.age = age;
      }
      // 类的所有方法都定义在类的prototype属性上面
      
      running() {
        console.log("running");
      }
    }

    class Student extends Person {
      constructor(name, age, sno) {
        // ES6 规定，子类必须在constructor()方法中调用super()，否则就会报错。
        // 这是因为子类自己的this对象，必须先通过父类的构造函数完成塑造，得到与父类同样的实例属性和方法，
        // 然后再对其进行加工，添加子类自己的实例属性和方法。如果不调用super()方法，
        // 子类就得不到自己的this对象。
        super(name, age);
        this.sno = sno;
      }
    }

    // hasOwnProperty(propertyName)方法 是用来检测属性是否为对象的自有属性，如果是，返回true，否者false;
    const stu = new Student("why", 18, 110);
    const per = new Person('ys',20)
    // hasOwnProperty 只会检查对象的自有属性，对象原形上的属性其不会检测
    console.log("stu.hasOwnProperty('name')",stu.hasOwnProperty('name')); // true
    console.log("stu.hasOwnProperty('age')",stu.hasOwnProperty('age')); // true
    console.log("stu.hasOwnProperty('running')",stu.hasOwnProperty('running')); // false
    // stu的__proto__ 是
    console.log("stu.__proto__.hasOwnProperty('running')",stu.__proto__.hasOwnProperty('running'));// false
    console.log("per.hasOwnProperty('running')",per.hasOwnProperty('running')); // false
    console.log("per.__proto__.hasOwnProperty('running')",per.__proto__.hasOwnProperty('running')); // true
    console.log(stu.name, stu.age, stu.sno);
    stu.running();


    // class Teacher extends Person {
    //   constructor(name, age, title) {
    //     // 子类中是必须初始化父类对象
    //     super(name, age);
    //     this.title = title;
    //   }
    // }

    // const teacher = new Teacher("kobe", 40, "教练");
    // console.log(teacher.name, teacher.age, teacher.title);
    // teacher.running();

    // class Student {
    //   constructor(name, age, sno) {
    //     this.name = name;
    //     this.age = age;
    //     this.sno = sno;
    //   }

    //   running() {
    //     console.log("running");
    //   }
    // }

    // class Teacher {
    //   constructor(name, age, title) {
    //     this.name = name;
    //     this.age = age;
    //     this.title = title;
    //   }

    //   running() {
    //     console.log("running");
    //   }
    // }

  </script>
</body>
</html>